<template>
    <form class="validate-form-container">
        <slot name="default"></slot>    <!-- 存放表单元素的插槽 -->
        <div class="submit-area" @click.prevent="submitForm">
            <slot name="submit">    <!-- 存放提交按钮的插槽,@click.prevent阻止事件的默认行为 -->
                <button type="submit" class="btn btn-primary">提交</button> 
            </slot>
        </div>  
    </form>
</template>

<script lang="ts">
import {defineComponent,onUnmounted} from 'vue'
// 使用mitt事件总线是为了在两个组件不是父子关系的情况下，实现通信（数据传递）
import mitt from 'mitt'
type ValidateFunc = ()=>boolean //定义ValidateFunc类型是一个返回boolean值的方法
export const emitter = mitt()   //创建mitt完成，将emitter变量暴露出去给ValidateInput.vue使用
export default defineComponent({    //主要处理点击提交按钮后，对每个表单进行验证
    emits:['form-submit'],
    setup(props,context){
        let funcArr:ValidateFunc[] = [] //funcArr存储ValidateFunc类型方法数组，里面装的都是返回boolean值的元素
        const submitForm=()=>{  //点击提交触发的函数
            //将数组中存的方法每个都执行一遍，结果为boolean数组，然后查找其中有没有false，有就直接返回，不再往下执行
            //里面存的虽然都是validateInput方法，但是组件内的每个validateInput不一样
            const result=funcArr.map(func=>func()).every(result=>result)    
            context.emit('form-submit',result)  //输入的登陆信息是否符合验证规则，将boolean类型的result传递给Login.vue组件(子->父)
        }
        const callback = (func:any)=>{  //将方法添加到数组
            funcArr.push(func)
        }
        //监听器，监听事件为form-item-created，调用callback方法
        emitter.on('form-item-created',callback)    
        onUnmounted(()=>{   //Vue实例销毁后调用
            emitter.off('form-item-created',callback)//组件卸载后停止监听form-item-created事件
            funcArr=[]  //将数组中的函数清空
        })
        return {
            submitForm
        }
    }
})
</script>